
/**
  ******************************************************************************
  * Copyright 2021 The Microbee Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       log_structure.h
  * @author     baiyang
  * @date       2023-2-23
  ******************************************************************************
  */

#pragma once

#ifdef __cplusplus
extern "C"{
#endif

/*----------------------------------include-----------------------------------*/
#include <stdint.h>
#include <stdbool.h>
/*-----------------------------------macro------------------------------------*/
// once the logging code is all converted we will remove these from
// this header
#define APLOG_HEAD_BYTE1  0xA3    // Decimal 163
#define APLOG_HEAD_BYTE2  0x95    // Decimal 149

/*
  unfortunately these need to be macros because of a limitation of
  named member structure initialisation in g++
 */
#define APLOG_PACKET_HEADER          uint8_t head1, head2, msgid

#define APLOG_PACKET_HEADER_INIT(id) \
    .head1 = APLOG_HEAD_BYTE1,       \
    .head2 = APLOG_HEAD_BYTE2,       \
    .msgid = id

#define APLOG_PACKET_HEADER_LEN 3 // bytes required for APLOG_PACKET_HEADER

// maximum lengths of fields in LogStructure, including trailing nulls
#define LS_NAME_SIZE        5
#define LS_FORMAT_SIZE      17
#define LS_LABELS_SIZE      65
#define LS_UNITS_SIZE       17
#define LS_MULTIPLIERS_SIZE 17

// FMT messages define all message formats other than FMT
// UNIT messages define units which can be referenced by FMTU messages
// FMTU messages associate types (e.g. centimeters/second/second) to FMT message fields

#define PID_LABELS "TimeUS,Tar,Act,Err,P,I,D,FF,Dmod,SRate,Limit"
#define PID_FMT    "QfffffffffB"
#define PID_UNITS  "s----------"
#define PID_MULTS  "F----------"

#define LOG_IDS_FROM_INERTIALSENSOR \
    LOG_ACC_MSG, \
    LOG_GYR_MSG, \
    LOG_IMU_MSG, \
    LOG_ISBH_MSG, \
    LOG_ISBD_MSG, \
    LOG_VIBE_MSG

#define LOG_STRUCTURE_FROM_INERTIALSENSOR        \
    { LOG_ACC_MSG, sizeof(struct log_ACC), \
      "ACC", "QBQfff",        "TimeUS,I,SampleUS,AccX,AccY,AccZ", "s#sooo", "F-F000" , true }, \
    { LOG_GYR_MSG, sizeof(struct log_GYR), \
      "GYR", "QBQfff",        "TimeUS,I,SampleUS,GyrX,GyrY,GyrZ", "s#sEEE", "F-F000" , true }, \
    { LOG_IMU_MSG, sizeof(struct log_IMU), \
      "IMU",  "QBffffffIIfBBHH", "TimeUS,I,GyrX,GyrY,GyrZ,AccX,AccY,AccZ,EG,EA,T,GH,AH,GHz,AHz", "s#EEEooo--O--zz", "F-000000-----00" , true }, \
    { LOG_VIBE_MSG, sizeof(struct log_Vibe), \
      "VIBE", "QBfffI", "TimeUS,IMU,VibeX,VibeY,VibeZ,Clip", "s#ooo-", "F-000-" , true }, \
    { LOG_ISBH_MSG, sizeof(struct log_ISBH), \
      "ISBH", "QHBBHHQf", "TimeUS,N,type,instance,mul,smp_cnt,SampleUS,smp_rate", "s-----sz", "F-----F-" },  \
    { LOG_ISBD_MSG, sizeof(struct log_ISBD), \
      "ISBD", "QHHaaa", "TimeUS,N,seqno,x,y,z", "s--ooo", "F--???" },

#define LOG_IDS_FROM_BARO \
    LOG_BARO_MSG, \
    LOG_BARD_MSG

#define LOG_STRUCTURE_FROM_BARO                                         \
    { LOG_BARO_MSG, sizeof(struct log_BARO),                                   \
            "BARO",                                                     \
            "Q"       "B"  "f"    "f"      "c"     "f"    "I"    "f"       "f"        "B", \
            "TimeUS," "I," "Alt," "Press," "Temp," "CRt," "SMS," "Offset," "GndTemp," "Health", \
            "s"       "#"  "m"    "P"      "O"     "n"    "s"    "m"       "O"        "-", \
            "F"       "-"  "0"    "0"      "B"     "0"    "C"    "?"       "0"        "-", \
            true                                                        \
            },                                                          \
    { LOG_BARD_MSG, sizeof(struct log_BARD),                                   \
            "BARD",                                                     \
            "Q"       "B"  "fff", \
            "TimeUS," "I," "DynPrX,DynPrY,DynPrZ", \
            "s"       "#"  "PPP", \
            "F"       "-"  "000", \
            true                                                        \
            },

#define LOG_IDS_FROM_GPS                        \
    LOG_GPS_MSG,                                \
    LOG_GPA_MSG,                                \
    LOG_GPS_RAW_MSG,                            \
    LOG_GPS_RAWH_MSG,                           \
    LOG_GPS_RAWS_MSG,                           \
    LOG_GPS_UBX1_MSG,                           \
    LOG_GPS_UBX2_MSG

#define LOG_STRUCTURE_FROM_GPS \
    { LOG_GPS_MSG, sizeof(struct log_GPS), \
      "GPS",  "QBBIHBcLLeffffB", "TimeUS,I,Status,GMS,GWk,NSats,HDop,Lat,Lng,Alt,Spd,GCrs,VZ,Yaw,U", "s#---SmDUmnhnh-", "F----0BGGB000--" , true }, \
    { LOG_GPA_MSG,  sizeof(struct log_GPA), \
      "GPA",  "QBCCCCfBIHf", "TimeUS,I,VDop,HAcc,VAcc,SAcc,YAcc,VV,SMS,Delta,Und", "s#mmmnd-ssm", "F-BBBB0-CC0" , true }, \
    { LOG_GPS_UBX1_MSG, sizeof(struct log_Ubx1), \
      "UBX1", "QBHBBHI",  "TimeUS,Instance,noisePerMS,jamInd,aPower,agcCnt,config", "s#-----", "F------"  , true }, \
    { LOG_GPS_UBX2_MSG, sizeof(struct log_Ubx2), \
      "UBX2", "QBbBbB", "TimeUS,Instance,ofsI,magI,ofsQ,magQ", "s#----", "F-----" , true }, \
    { LOG_GPS_RAW_MSG, sizeof(struct log_GPS_RAW), \
      "GRAW", "QIHBBddfBbB", "TimeUS,WkMS,Week,numSV,sv,cpMes,prMes,doMes,mesQI,cno,lli", "s--S-------", "F--0-------" , true }, \
    { LOG_GPS_RAWH_MSG, sizeof(struct log_GPS_RAWH), \
      "GRXH", "QdHbBB", "TimeUS,rcvTime,week,leapS,numMeas,recStat", "s-----", "F-----" , true }, \
    { LOG_GPS_RAWS_MSG, sizeof(struct log_GPS_RAWS), \
      "GRXS", "QddfBBBHBBBBB", "TimeUS,prMes,cpMes,doMes,gnss,sv,freq,lock,cno,prD,cpD,doD,trk", "s------------", "F------------" , true },

#define LOG_IDS_FROM_AHRS \
    LOG_AHR2_MSG, \
    LOG_AOA_SSA_MSG, \
    LOG_ATTITUDE_MSG, \
    LOG_ORGN_MSG, \
    LOG_POS_MSG, \
    LOG_RATE_MSG, \
    LOG_ATSC_MSG

#define LOG_STRUCTURE_FROM_AHRS \
    { LOG_AHR2_MSG, sizeof(struct log_AHRS), \
        "AHR2","QccCfLLffff","TimeUS,Roll,Pitch,Yaw,Alt,Lat,Lng,Q1,Q2,Q3,Q4","sddhmDU????", "FBBB0GG????" , true }, \
    { LOG_AOA_SSA_MSG, sizeof(struct log_AOA_SSA), \
        "AOA", "Qff", "TimeUS,AOA,SSA", "sdd", "F00" , true }, \
    { LOG_ATTITUDE_MSG, sizeof(struct log_Attitude),\
        "ATT", "QccccCCCCB", "TimeUS,DesRoll,Roll,DesPitch,Pitch,DesYaw,Yaw,ErrRP,ErrYaw,AEKF", "sddddhhdh-", "FBBBBBBBB-" , true }, \
    { LOG_ORGN_MSG, sizeof(struct log_ORGN), \
        "ORGN","QBLLe","TimeUS,Type,Lat,Lng,Alt", "s#DUm", "F-GGB" }, \
    { LOG_POS_MSG, sizeof(struct log_POS), \
        "POS","QLLfff","TimeUS,Lat,Lng,Alt,RelHomeAlt,RelOriginAlt", "sDUmmm", "FGG000" , true }, \
    { LOG_RATE_MSG, sizeof(struct log_Rate), \
        "RATE", "Qfffffffffffff",  "TimeUS,RDes,R,ROut,PDes,P,POut,YDes,Y,YOut,ADes,A,AOut,AOutSlew", "skk-kk-kk-oo--", "F?????????BB--" , true }, \
    { LOG_ATSC_MSG, sizeof(struct log_ATSC), \
        "ATSC", "Qffffff",  "TimeUS,AngPScX,AngPScY,AngPScZ,PDScX,PDScY,PDScZ", "s------", "F000000" , true }, \
    { LOG_VIDEO_STABILISATION_MSG, sizeof(struct log_Video_Stabilisation), \
        "VSTB", "Qffffffffff",  "TimeUS,GyrX,GyrY,GyrZ,AccX,AccY,AccZ,Q1,Q2,Q3,Q4", "sEEEooo????", "F000000????" },

#define KY0_FMT "QBffffffffffff"
#define KY0_LABELS "TimeUS,C,YC,YCS,Y0,Y1,Y2,Y3,Y4,W0,W1,W2,W3,W4"
#define KY0_UNITS "s#hdhhhhh-----"
#define KY0_MULTS "F-000000000000"

#define KY1_FMT "QBffffffffff"
#define KY1_LABELS "TimeUS,C,IVN0,IVN1,IVN2,IVN3,IVN4,IVE0,IVE1,IVE2,IVE3,IVE4"
#define KY1_UNITS "s#nnnnnnnnnn"
#define KY1_MULTS "F-0000000000"

#define LOG_IDS_FROM_NAVEKF2 \
    LOG_MKF0_MSG,  \
    LOG_MKF1_MSG,  \
    LOG_MKF2_MSG,  \
    LOG_MKF3_MSG,  \
    LOG_MKF4_MSG,  \
    LOG_MKF5_MSG,  \
    LOG_MKF6_MSG,  \
    LOG_MKF7_MSG,  \
    LOG_MKF8_MSG,  \
    LOG_MKF9_MSG

#define LOG_STRUCTURE_FROM_NAVEKF2        \
    { LOG_MKF0_MSG, sizeof(struct log_MKF0), \
      "MKF0","QBcccccccccccc","TimeUS,C,IGVN,IGVE,IGVD,IGN,IGE,IGD,IEVN,IEVE,IEVD,IEN,IEE,IED", "s#nnnmmmnnnmmm", "F-BBBBBBBBBBBB" , true }, \
    { LOG_MKF1_MSG, sizeof(struct log_MKF1), \
      "MKF1","QBccccccccccc","TimeUS,C,IRng,IBaro,IAVN,IAVE,IAVD,IFX,IFY,IHead,IMX,IMY,IMZ", "s#mmnnnrrrGGG", "F-BBBBBBBBBBB" , true }, \
    { LOG_MKF2_MSG, sizeof(struct log_MKF2), \
      "MKF2","QBcccccc","TimeUS,C,IDragX,IDragY,IairS,IBeta,IHgl,IHglR", "s#oonnmn", "F-BBBBBB" , true }, \
    { LOG_MKF3_MSG, sizeof(struct log_MKF3), \
      "MKF3","QBQfffIff","TimeUS,C,CtrlMF,TraErrA,TraErrV,TraErrP,FaF,PHAcc,PVAcc", "s#brnm-mm", "F-?------" , true }, \
    { LOG_MKF4_MSG, sizeof(struct log_MKF4), \
      "MKF4","QBffffffffHHH","TimeUS,C,MTR,VTR,PTR,HTR,TTR,HLTR,BTR,SlipT,GFF,ICF,SSF", "s#-------s---", "F---------" , true }, \
    { LOG_MKF5_MSG, sizeof(struct log_MKF5), \
      "MKF5","QBBBBBBB","TimeUS,C,RVNE,RVD,RPNE,RPD,RQ,PreFMag", "s#------", "F-------" , true }, \
    { LOG_MKF6_MSG, sizeof(struct log_MKF6), \
      "MKF6","QBBffffff","TimeUS,C,gVal,GX,GY,GZ,GXV,GYV,GZV", "s#-EEE---", "F--000---" , true }, \
    { LOG_MKF7_MSG, sizeof(struct log_MKF7), \
      "MKF7","QBBffffff","TimeUS,C,aVal,AX,AY,AZ,AXV,AYV,AZV", "s#-ooo---", "F--000---" , true }, \
    { LOG_MKF8_MSG, sizeof(struct log_MKF8),                                    \
      "MKF8", KY0_FMT, KY0_LABELS, KY0_UNITS, KY0_MULTS, true },                \
    { LOG_MKF9_MSG, sizeof(struct log_MKF9),                                            \
      "MKF9", KY1_FMT, KY1_LABELS, KY1_UNITS, KY1_MULTS , true },

// messages for all boards
#define LOG_COMMON_STRUCTURES \
    { LOG_FORMAT_MSG, sizeof(struct log_Format), \
      "FMT", "BBnNZ",      "Type,Length,Name,Format,Columns", "-b---", "-----" },    \
    { LOG_UNIT_MSG, sizeof(struct log_Unit), \
      "UNIT", "QbZ",      "TimeUS,Id,Label", "s--","F--" },    \
    { LOG_FORMAT_UNITS_MSG, sizeof(struct log_Format_Units), \
      "FMTU", "QBNN",      "TimeUS,FmtType,UnitIds,MultIds","s---", "F---" },   \
    { LOG_MULT_MSG, sizeof(struct log_Format_Multiplier), \
      "MULT", "Qbd",      "TimeUS,Id,Mult", "s--","F--" },   \
    { LOG_PARAMETER_MSG, sizeof(struct log_Parameter), \
     "PARM", "QNff",        "TimeUS,Name,Value,Default", "s---", "F---"  },       \
    { LOG_MESSAGE_MSG, sizeof(struct log_Message), \
      "MSG",  "QZ",     "TimeUS,Message", "s-", "F-"}, \
    { LOG_RCIN_MSG, sizeof(struct log_RCIN), \
      "RCIN",  "QHHHHHHHHHHHHHH",     "TimeUS,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14", "sYYYYYYYYYYYYYY", "F--------------", true }, \
    { LOG_RCIN2_MSG, sizeof(struct log_RCIN2), \
      "RCI2",  "QHHH",     "TimeUS,C15,C16,OMask", "sYY-", "F---", true }, \
    { LOG_RCOUT_MSG, sizeof(struct log_RCOUT), \
      "RCOU",  "QHHHHHHHHHHHHHH",     "TimeUS,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14", "sYYYYYYYYYYYYYY", "F--------------", true  }, \
    { LOG_RCOUT2_MSG, sizeof(struct log_RCOUT2), \
      "RCO2",  "QHHHH",     "TimeUS,C15,C16,C17,C18", "sYYYY", "F----", true  }, \
    { LOG_RCOUT3_MSG, sizeof(struct log_RCOUT), \
      "RCO3",  "QHHHHHHHHHHHHHH",     "TimeUS,C19,C20,C21,C22,C23,C24,C25,C26,C27,C28,C29,C30,C31,C32", "sYYYYYYYYYYYYYY", "F--------------", true  }, \
    { LOG_POWR_MSG, sizeof(struct log_POWR), \
      "POWR","QffHHB","TimeUS,Vcc,VServo,Flags,AccFlags,Safety", "svv---", "F00---", true }, \
    { LOG_CMD_MSG, sizeof(struct log_Cmd), \
      "CMD", "QHHHffffLLfB","TimeUS,CTot,CNum,CId,Prm1,Prm2,Prm3,Prm4,Lat,Lng,Alt,Frame", "s-------DUm-", "F-------GG0-" }, \
    { LOG_MAVLINK_COMMAND_MSG, sizeof(struct log_MAVLink_Command), \
      "MAVC", "QBBBBBHffffiifBB","TimeUS,TS,TC,SS,SC,Fr,Cmd,P1,P2,P3,P4,X,Y,Z,Res,WL", "s---------------", "F---------------" }, \
    { LOG_MAG_MSG, sizeof(struct log_MAG), \
      "MAG", "QBhhhhhhhhhBI",    "TimeUS,I,MagX,MagY,MagZ,OfsX,OfsY,OfsZ,MOX,MOY,MOZ,Health,S", "s#GGGGGGGGG-s", "F-CCCCCCCCC-F", true }, \
    { LOG_MODE_MSG, sizeof(struct log_Mode), \
      "MODE", "QMBB",         "TimeUS,Mode,ModeNum,Rsn", "s---", "F---" }, \
    { LOG_RFND_MSG, sizeof(struct log_RFND), \
      "RFND", "QBCBB", "TimeUS,Instance,Dist,Stat,Orient", "s#m--", "F-B--", true }, \
    { LOG_PIDR_MSG, sizeof(struct log_PID), \
      "PIDR", PID_FMT,  PID_LABELS, PID_UNITS, PID_MULTS, true },  \
    { LOG_PIDP_MSG, sizeof(struct log_PID), \
      "PIDP", PID_FMT,  PID_LABELS, PID_UNITS, PID_MULTS , true }, \
    { LOG_PIDY_MSG, sizeof(struct log_PID), \
      "PIDY", PID_FMT,  PID_LABELS, PID_UNITS, PID_MULTS , true }, \
    { LOG_PIDA_MSG, sizeof(struct log_PID), \
      "PIDA", PID_FMT,  PID_LABELS, PID_UNITS, PID_MULTS , true }, \
    { LOG_PIDS_MSG, sizeof(struct log_PID), \
      "PIDS", PID_FMT,  PID_LABELS, PID_UNITS, PID_MULTS , true }, \
    { LOG_PIDN_MSG, sizeof(struct log_PID), \
      "PIDN", PID_FMT,  PID_LABELS, PID_UNITS, PID_MULTS , true }, \
    { LOG_PIDE_MSG, sizeof(struct log_PID), \
      "PIDE", PID_FMT,  PID_LABELS, PID_UNITS, PID_MULTS , true }, \
    LOG_STRUCTURE_FROM_INERTIALSENSOR \
    LOG_STRUCTURE_FROM_BARO \
    LOG_STRUCTURE_FROM_GPS \
    LOG_STRUCTURE_FROM_AHRS \
    LOG_STRUCTURE_FROM_NAVEKF2 \
    { LOG_EVENT_MSG, sizeof(struct log_Event), \
      "EV",   "QB",           "TimeUS,Id", "s-", "F-" }, \
    { LOG_ARM_DISARM_MSG, sizeof(struct log_Arm_Disarm), \
      "ARM", "QBIBB", "TimeUS,ArmState,ArmChecks,Forced,Method", "s----", "F----" }, \
    { LOG_ERROR_MSG, sizeof(struct log_Error), \
      "ERR",   "QBB",         "TimeUS,Subsys,ECode", "s--", "F--" }, \
    { LOG_PSCN_MSG, sizeof(struct log_PSCN), \
      "PSCN", "Qffffffff", "TimeUS,TPN,PN,DVN,TVN,VN,DAN,TAN,AN", "smmnnnooo", "F00000000" }, \
    { LOG_PSCE_MSG, sizeof(struct log_PSCE), \
      "PSCE", "Qffffffff", "TimeUS,TPE,PE,DVE,TVE,VE,DAE,TAE,AE", "smmnnnooo", "F00000000" }, \
    { LOG_PSCD_MSG, sizeof(struct log_PSCD), \
      "PSCD", "Qffffffff", "TimeUS,TPD,PD,DVD,TVD,VD,DAD,TAD,AD", "smmnnnooo", "F00000000" }, \
    { LOG_VER_MSG, sizeof(struct log_VER), \
      "VER",   "QBHBBBBIZH", "TimeUS,BT,BST,Maj,Min,Pat,FWT,GH,FWS,APJ", "s---------", "F---------", false }, \
    { LOG_ARSP_MSG, sizeof(struct log_ARSP), "ARSP",  "QBffcffBBffB", "TimeUS,I,Airspeed,DiffPress,Temp,RawPress,Offset,U,H,Hp,TR,Pri", "s#nPOPP-----", "F-00B00-----", true }

/*----------------------------------typedef-----------------------------------*/
/*
Format characters in the format string for binary log messages
  a   : int16_t[32]
  b   : int8_t
  B   : uint8_t
  h   : int16_t
  H   : uint16_t
  i   : int32_t
  I   : uint32_t
  f   : float
  d   : double
  n   : char[4]
  N   : char[16]
  Z   : char[64]
  c   : int16_t * 100
  C   : uint16_t * 100
  e   : int32_t * 100
  E   : uint32_t * 100
  L   : int32_t latitude/longitude
  M   : uint8_t flight mode
  q   : int64_t
  Q   : uint64_t
 */
struct UnitStructure {
    const char ID;
    const char *unit;
};

struct MultiplierStructure {
    const char ID;
    const double multiplier;
};

// message types for common messages
enum LogMessages {
    LOG_PARAMETER_MSG = 32,
    LOG_IDS_FROM_NAVEKF2,
    LOG_IDS_FROM_NAVEKF3,
    LOG_MESSAGE_MSG,
    LOG_RCIN_MSG,
    LOG_RCIN2_MSG,
    LOG_RCOUT_MSG,
    LOG_RSSI_MSG,
    LOG_IDS_FROM_BARO,
    LOG_POWR_MSG,
    LOG_MCU_MSG,
    LOG_IDS_FROM_AHRS,
    LOG_SIMSTATE_MSG,
    LOG_CMD_MSG,
    LOG_MAVLINK_COMMAND_MSG,
    LOG_RADIO_MSG,
    LOG_ATRP_MSG,
    LOG_IDS_FROM_CAMERA,
    LOG_TERRAIN_MSG,
    LOG_CSRV_MSG,
    LOG_IDS_FROM_ESC_TELEM,
    LOG_IDS_FROM_BATTMONITOR,
    LOG_IDS_FROM_HAL_CHIBIOS,

    LOG_IDS_FROM_GPS,

    LOG_PIDR_MSG,
    LOG_PIDP_MSG,
    LOG_PIDY_MSG,
    LOG_PIDA_MSG,
    LOG_PIDS_MSG,
    LOG_PIDN_MSG,
    LOG_PIDE_MSG,
    LOG_DSTL_MSG,
    LOG_MAG_MSG,
    LOG_ARSP_MSG,
    LOG_IDS_FROM_RPM,
    LOG_RFND_MSG,
    LOG_MAV_STATS,
    LOG_FORMAT_UNITS_MSG,
    LOG_UNIT_MSG,
    LOG_MULT_MSG,
    LOG_RALLY_MSG,

    // LOG_MODE_MSG is used as a check for duplicates. Do not add between this and LOG_FORMAT_MSG
    LOG_MODE_MSG,

    LOG_FORMAT_MSG = 128, // this must remain #128

    LOG_IDS_FROM_DAL,
    LOG_IDS_FROM_INERTIALSENSOR,

    LOG_IDS_FROM_VISUALODOM,
    LOG_IDS_FROM_AVOIDANCE,
    LOG_IDS_FROM_BEACON,
    LOG_IDS_FROM_PROXIMITY,
    LOG_DF_FILE_STATS,
    LOG_SRTL_MSG,
    LOG_PERFORMANCE_MSG,
    LOG_OPTFLOW_MSG,
    LOG_EVENT_MSG,
    LOG_WHEELENCODER_MSG,
    LOG_MAV_MSG,
    LOG_ERROR_MSG,
    LOG_ADSB_MSG,
    LOG_ARM_DISARM_MSG,
    LOG_WINCH_MSG,
    LOG_PSCN_MSG,
    LOG_PSCE_MSG,
    LOG_PSCD_MSG,
    LOG_IDS_FROM_PRECLAND,
    LOG_IDS_FROM_AIS,
    LOG_STAK_MSG,
    LOG_FILE_MSG,
    LOG_SCRIPTING_MSG,
    LOG_VIDEO_STABILISATION_MSG,
    LOG_MOTBATT_MSG,
    LOG_VER_MSG,
    LOG_RCOUT2_MSG,
    LOG_RCOUT3_MSG,
    LOG_IDS_FROM_FENCE,

    _LOG_LAST_MSG_
};

// structure used to define logging format
// It is packed on ChibiOS to save flash space; however, this causes problems
// when building the SITL on an Apple M1 CPU (and is also slower) so we do not
// pack it by default
struct LogStructure {
    uint8_t msg_type;
    uint8_t msg_len;
    const char *name;
    const char *format;
    const char *labels;
    const char *units;
    const char *multipliers;
    bool streaming; // can be rate limited
};

#pragma pack(1)
/*
  log structures common to all vehicle types
 */
struct log_Format {
    APLOG_PACKET_HEADER;
    uint8_t type;
    uint8_t length;
    char name[4];
    char format[16];
    char labels[64];
};

struct log_Unit {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    char type;
    char unit[64]; // you know, this might be overkill...
};

struct log_Format_Multiplier {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    char type;
    double multiplier;
};

struct log_Format_Units {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t format_type;
    char units[16];
    char multipliers[16];
};

struct log_Parameter {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    char name[16];
    float value;
    float default_value;
};

struct log_DSF {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint32_t dropped;
    uint16_t blocks;
    uint32_t bytes;
    uint32_t buf_space_min;
    uint32_t buf_space_max;
    uint32_t buf_space_avg;
};

struct log_Event {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t id;
};

struct log_Error {
  APLOG_PACKET_HEADER;
  uint64_t time_us;
  uint8_t sub_system;
  uint8_t error_code;
};

struct log_Message {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    char msg[64];
};

// @LoggerMessage: ACC
// @Description: IMU accelerometer data
// @Field: TimeUS: Time since system startup
// @Field: I: accelerometer sensor instance number
// @Field: SampleUS: time since system startup this sample was taken
// @Field: AccX: acceleration along X axis
// @Field: AccY: acceleration along Y axis
// @Field: AccZ: acceleration along Z axis
struct log_ACC {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t instance;
    uint64_t sample_us;
    float AccX, AccY, AccZ;
};

// @LoggerMessage: GYR
// @Description: IMU gyroscope data
// @Field: TimeUS: Time since system startup
// @Field: I: gyroscope sensor instance number
// @Field: SampleUS: time since system startup this sample was taken
// @Field: GyrX: measured rotation rate about X axis
// @Field: GyrY: measured rotation rate about Y axis
// @Field: GyrZ: measured rotation rate about Z axis
struct log_GYR {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t instance;
    uint64_t sample_us;
    float GyrX, GyrY, GyrZ;
};

// @LoggerMessage: IMU
// @Description: Inertial Measurement Unit data
// @Field: TimeUS: Time since system startup
// @Field: I: IMU sensor instance number
// @Field: GyrX: measured rotation rate about X axis
// @Field: GyrY: measured rotation rate about Y axis
// @Field: GyrZ: measured rotation rate about Z axis
// @Field: AccX: acceleration along X axis
// @Field: AccY: acceleration along Y axis
// @Field: AccZ: acceleration along Z axis
// @Field: EG: gyroscope error count
// @Field: EA: accelerometer error count
// @Field: T: IMU temperature
// @Field: GH: gyroscope health
// @Field: AH: accelerometer health
// @Field: GHz: gyroscope measurement rate
// @Field: AHz: accelerometer measurement rate
struct log_IMU {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t instance;
    float gyro_x, gyro_y, gyro_z;
    float accel_x, accel_y, accel_z;
    uint32_t gyro_error, accel_error;
    float temperature;
    uint8_t gyro_health, accel_health;
    uint16_t gyro_rate, accel_rate;
};

struct log_ISBH {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint16_t seqno;
    uint8_t sensor_type; // e.g. GYRO or ACCEL
    uint8_t instance;
    uint16_t multiplier;
    uint16_t sample_count;
    uint64_t sample_us;
    float sample_rate_hz;
};

struct log_ISBD {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint16_t isb_seqno;
    uint16_t seqno; // seqno within isb_seqno
    int16_t x[32];
    int16_t y[32];
    int16_t z[32];
};

// @LoggerMessage: VIBE
// @Description: Processed (acceleration) vibration information
// @Field: TimeUS: Time since system startup
// @Field: IMU: Vibration instance number
// @Field: VibeX: Primary accelerometer filtered vibration, x-axis
// @Field: VibeY: Primary accelerometer filtered vibration, y-axis
// @Field: VibeZ: Primary accelerometer filtered vibration, z-axis
// @Field: Clip: Number of clipping events on 1st accelerometer
struct log_Vibe {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t imu;
    float vibe_x, vibe_y, vibe_z;
    uint32_t clipping;
};

// @LoggerMessage: BARO
// @Description: Gathered Barometer data
// @Field: TimeUS: Time since system startup
// @Field: I: barometer sensor instance number
// @Field: Alt: calculated altitude
// @Field: Press: measured atmospheric pressure
// @Field: Temp: measured atmospheric temperature
// @Field: CRt: derived climb rate from primary barometer
// @Field: SMS: time last sample was taken
// @Field: Offset: raw adjustment of barometer altitude, zeroed on calibration, possibly set by GCS
// @Field: GndTemp: temperature on ground, specified by parameter or measured while on ground
// @Field: Health: true if barometer is considered healthy
struct log_BARO {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t instance;
    float   altitude;
    float   pressure;
    int16_t temperature;
    float   climbrate;
    uint32_t sample_time_ms;
    float   drift_offset;
    float   ground_temp;
    uint8_t healthy;
};

// @LoggerMessage: BARD
// @Description: Barometer dynamic data
// @Field: TimeUS: Time since system startup
// @Field: I: barometer sensor instance number
// @Field: DynPrX: calculated dynamic pressure in the bodyframe X-axis
// @Field: DynPrY: calculated dynamic pressure in the bodyframe Y-axis
// @Field: DynPrZ: calculated dynamic pressure in the bodyframe Z-axis
struct log_BARD {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t instance;
    float dyn_pressure_x;
    float dyn_pressure_y;
    float dyn_pressure_z;
};

struct log_MAG {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t  instance;
    int16_t  mag_x;
    int16_t  mag_y;
    int16_t  mag_z;
    int16_t  offset_x;
    int16_t  offset_y;
    int16_t  offset_z;
    int16_t  motor_offset_x;
    int16_t  motor_offset_y;
    int16_t  motor_offset_z;
    uint8_t  health;
    uint32_t SUS;
};

// @LoggerMessage: GPS
// @Description: Information received from GNSS systems attached to the autopilot
// @Field: TimeUS: Time since system startup
// @Field: I: GPS instance number
// @Field: Status: GPS Fix type; 2D fix, 3D fix etc.
// @Field: GMS: milliseconds since start of GPS Week
// @Field: GWk: weeks since 5 Jan 1980
// @Field: NSats: number of satellites visible
// @Field: HDop: horizontal precision
// @Field: Lat: latitude
// @Field: Lng: longitude
// @Field: Alt: altitude
// @Field: Spd: ground speed
// @Field: GCrs: ground course
// @Field: VZ: vertical speed
// @Field: Yaw: vehicle yaw
// @Field: U: boolean value indicating whether this GPS is in use
struct log_GPS {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t  instance;
    uint8_t  status;
    uint32_t gps_week_ms;
    uint16_t gps_week;
    uint8_t  num_sats;
    uint16_t hdop;
    int32_t  latitude;
    int32_t  longitude;
    int32_t  altitude;
    float    ground_speed;
    float    ground_course;
    float    vel_z;
    float    yaw;
    uint8_t  used;
};

// @LoggerMessage: GPA
// @Description: GPS accuracy information
// @Field: I: GPS instance number
// @Field: TimeUS: Time since system startup
// @Field: VDop: vertical degree of procession
// @Field: HAcc: horizontal position accuracy
// @Field: VAcc: vertical position accuracy
// @Field: SAcc: speed accuracy
// @Field: YAcc: yaw accuracy
// @Field: VV: true if vertical velocity is available
// @Field: SMS: time since system startup this sample was taken
// @Field: Delta: system time delta between the last two reported positions
// @Field: Und: Undulation
struct log_GPA {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t  instance;
    uint16_t vdop;
    uint16_t hacc;
    uint16_t vacc;
    uint16_t sacc;
    float    yaw_accuracy;
    uint8_t  have_vv;
    uint32_t sample_ms;
    uint16_t delta_ms;
    float undulation;
};

/*
  UBlox logging
 */

// @LoggerMessage: UBX1
// @Description: uBlox-specific GPS information (part 1)
// @Field: TimeUS: Time since system startup
// @Field: Instance: GPS instance number
// @Field: noisePerMS: noise level as measured by GPS
// @Field: jamInd: jamming indicator; higher is more likely jammed
// @Field: aPower: antenna power indicator; 2 is don't know
// @Field: agcCnt: automatic gain control monitor
// @Field: config: bitmask for messages which haven't been seen
struct log_Ubx1 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t  instance;
    uint16_t noisePerMS;
    uint8_t  jamInd;
    uint8_t  aPower;
    uint16_t agcCnt;
    uint32_t config;
};

// @LoggerMessage: UBX2
// @Description: uBlox-specific GPS information (part 2)
// @Field: TimeUS: Time since system startup
// @Field: Instance: GPS instance number
// @Field: ofsI: imbalance of I part of complex signal
// @Field: magI: magnitude of I part of complex signal
// @Field: ofsQ: imbalance of Q part of complex signal
// @Field: magQ: magnitude of Q part of complex signal
struct log_Ubx2 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t  instance;
    int8_t   ofsI;
    uint8_t  magI;
    int8_t   ofsQ;
    uint8_t  magQ;
};

// @LoggerMessage: GRAW
// @Description: Raw uBlox data
// @Field: TimeUS: Time since system startup
// @Field: WkMS: receiver TimeOfWeek measurement
// @Field: Week: GPS week
// @Field: numSV: number of space vehicles seen
// @Field: sv: space vehicle number of first vehicle
// @Field: cpMes: carrier phase measurement
// @Field: prMes: pseudorange measurement
// @Field: doMes: Doppler measurement
// @Field: mesQI: measurement quality index
// @Field: cno: carrier-to-noise density ratio
// @Field: lli: loss of lock indicator
struct log_GPS_RAW {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    int32_t iTOW;
    int16_t week;
    uint8_t numSV;
    uint8_t sv;
    double cpMes;
    double prMes;
    float doMes;
    int8_t mesQI;
    int8_t cno;
    uint8_t lli;
};

// @LoggerMessage: GRXH
// @Description: Raw uBlox data - header
// @Field: TimeUS: Time since system startup
// @Field: rcvTime: receiver TimeOfWeek measurement
// @Field: week: GPS week
// @Field: leapS: GPS leap seconds
// @Field: numMeas: number of space-vehicle measurements to follow
// @Field: recStat: receiver tracking status bitfield
struct log_GPS_RAWH {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    double rcvTow;
    uint16_t week;
    int8_t leapS;
    uint8_t numMeas;
    uint8_t recStat;
};

// @LoggerMessage: GRXS
// @Description: Raw uBlox data - space-vehicle data
// @Field: TimeUS: Time since system startup
// @Field: prMes: Pseudorange measurement
// @Field: cpMes: Carrier phase measurement
// @Field: doMes: Doppler measurement
// @Field: gnss: GNSS identifier
// @Field: sv: Satellite identifier
// @Field: freq: GLONASS frequency slot
// @Field: lock: carrier phase locktime counter
// @Field: cno: carrier-to-noise density ratio
// @Field: prD: estimated pseudorange measurement standard deviation
// @Field: cpD: estimated carrier phase measurement standard deviation
// @Field: doD: estimated Doppler measurement standard deviation
// @Field: trk: tracking status bitfield
struct log_GPS_RAWS {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    double prMes;
    double cpMes;
    float doMes;
    uint8_t gnssId;
    uint8_t svId;
    uint8_t freqId;
    uint16_t locktime;
    uint8_t cno;
    uint8_t prStdev;
    uint8_t cpStdev;
    uint8_t doStdev;
    uint8_t trkStat;
};

// @LoggerMessage: AHR2
// @Description: Backup AHRS data
// @Field: TimeUS: Time since system startup
// @Field: Roll: Estimated roll
// @Field: Pitch: Estimated pitch
// @Field: Yaw: Estimated yaw
// @Field: Alt: Estimated altitude
// @Field: Lat: Estimated latitude
// @Field: Lng: Estimated longitude
// @Field: Q1: Estimated attitude quaternion component 1
// @Field: Q2: Estimated attitude quaternion component 2
// @Field: Q3: Estimated attitude quaternion component 3
// @Field: Q4: Estimated attitude quaternion component 4
struct log_AHRS {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    int16_t roll;
    int16_t pitch;
    uint16_t yaw;
    float alt;
    int32_t lat;
    int32_t lng;
    float q1, q2, q3, q4;
};

// @LoggerMessage: AOA
// @Description: Angle of attack and Side Slip Angle values
// @Field: TimeUS: Time since system startup
// @Field: AOA: Angle of Attack calculated from airspeed, wind vector,velocity vector 
// @Field: SSA: Side Slip Angle calculated from airspeed, wind vector,velocity vector
struct log_AOA_SSA {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    float AOA;
    float SSA;
};

// @LoggerMessage: ATT
// @Description: Canonical vehicle attitude
// @Field: TimeUS: Time since system startup
// @Field: DesRoll: vehicle desired roll
// @Field: Roll: achieved vehicle roll
// @Field: DesPitch: vehicle desired pitch
// @Field: Pitch: achieved vehicle pitch
// @Field: DesYaw: vehicle desired yaw
// @Field: Yaw: achieved vehicle yaw
// @Field: ErrRP: lowest estimated gyro drift error
// @Field: ErrYaw: difference between measured yaw and DCM yaw estimate
// @Field: AEKF: active EKF type
struct log_Attitude {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    int16_t  control_roll;
    int16_t  roll;
    int16_t  control_pitch;
    int16_t  pitch;
    uint16_t control_yaw;
    uint16_t yaw;
    uint16_t error_rp;
    uint16_t error_yaw;
    uint8_t  active;
};

// @LoggerMessage: ORGN
// @Description: Vehicle navigation origin or other notable position
// @Field: TimeUS: Time since system startup
// @Field: Type: Position type
// @FieldValueEnum: Type: AP_AHRS::LogOriginType
// @Field: Lat: Position latitude
// @Field: Lng: Position longitude
// @Field: Alt: Position altitude
struct log_ORGN {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t origin_type;
    int32_t latitude;
    int32_t longitude;
    int32_t altitude;
};

// @LoggerMessage: POS
// @Description: Canonical vehicle position
// @Field: TimeUS: Time since system startup
// @Field: Lat: Canonical vehicle latitude
// @Field: Lng: Canonical vehicle longitude
// @Field: Alt: Canonical vehicle altitude
// @Field: RelHomeAlt: Canonical vehicle altitude relative to home
// @Field: RelOriginAlt: Canonical vehicle altitude relative to navigation origin
struct log_POS {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    int32_t lat;
    int32_t lng;
    float alt;
    float rel_home_alt;
    float rel_origin_alt;
};

// @LoggerMessage: RATE
// @Description: Desired and achieved vehicle attitude rates. Not logged in Fixed Wing Plane modes.
// @Field: TimeUS: Time since system startup
// @Field: RDes: vehicle desired roll rate
// @Field: R: achieved vehicle roll rate
// @Field: ROut: normalized output for Roll
// @Field: PDes: vehicle desired pitch rate
// @Field: P: vehicle pitch rate
// @Field: POut: normalized output for Pitch
// @Field: Y: achieved vehicle yaw rate
// @Field: YOut: normalized output for Yaw
// @Field: YDes: vehicle desired yaw rate
// @Field: ADes: desired vehicle vertical acceleration
// @Field: A: achieved vehicle vertical acceleration
// @Field: AOut: percentage of vertical thrust output current being used
// @Field: AOutSlew: vertical thrust output slew rate
struct log_Rate {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    float   control_roll;
    float   roll;
    float   roll_out;
    float   control_pitch;
    float   pitch;
    float   pitch_out;
    float   control_yaw;
    float   yaw;
    float   yaw_out;
    float   control_accel;
    float   accel;
    float   accel_out;
    float   throttle_slew;
};

// @LoggerMessage: VSTB
// @Description: Log message for video stabilisation software such as Gyroflow
// @Field: TimeUS: Time since system startup
// @Field: GyrX: measured rotation rate about X axis
// @Field: GyrY: measured rotation rate about Y axis
// @Field: GyrZ: measured rotation rate about Z axis
// @Field: AccX: acceleration along X axis
// @Field: AccY: acceleration along Y axis
// @Field: AccZ: acceleration along Z axis
// @Field: Q1: Estimated attitude quaternion component 1
// @Field: Q2: Estimated attitude quaternion component 2
// @Field: Q3: Estimated attitude quaternion component 3
// @Field: Q4: Estimated attitude quaternion component 4

struct log_Video_Stabilisation {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    float gyro_x;
    float gyro_y;
    float gyro_z;
    float accel_x;
    float accel_y;
    float accel_z;
    float Q1;
    float Q2;
    float Q3;
    float Q4;
};

// @LoggerMessage: ATSC
// @Description: Scale factors for attitude controller
// @Field: TimeUS: Time since system startup
// @Field: AngPScX: Angle P scale X
// @Field: AngPScY: Angle P scale Y
// @Field: AngPScZ: Angle P scale Z
// @Field: PDScX: PD scale X
// @Field: PDScY: PD scale Y
// @Field: PDScZ: PD scale Z
struct log_ATSC {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    float scaleP_x;
    float scaleP_y;
    float scaleP_z;
    float scalePD_x;
    float scalePD_y;
    float scalePD_z;
};

struct log_RCIN {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint16_t chan1;
    uint16_t chan2;
    uint16_t chan3;
    uint16_t chan4;
    uint16_t chan5;
    uint16_t chan6;
    uint16_t chan7;
    uint16_t chan8;
    uint16_t chan9;
    uint16_t chan10;
    uint16_t chan11;
    uint16_t chan12;
    uint16_t chan13;
    uint16_t chan14;
};

struct log_RCIN2 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint16_t chan15;
    uint16_t chan16;
    uint16_t override_mask;
};

struct log_RCOUT {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint16_t chan1;
    uint16_t chan2;
    uint16_t chan3;
    uint16_t chan4;
    uint16_t chan5;
    uint16_t chan6;
    uint16_t chan7;
    uint16_t chan8;
    uint16_t chan9;
    uint16_t chan10;
    uint16_t chan11;
    uint16_t chan12;
    uint16_t chan13;
    uint16_t chan14;
};

struct log_RCOUT2 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint16_t chan15;
    uint16_t chan16;
    uint16_t chan17;
    uint16_t chan18;
};

struct log_POWR {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    float Vcc;
    float Vservo;
    uint16_t flags;
    uint16_t accumulated_flags;
    uint8_t safety_and_arm;
};

struct log_Cmd {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint16_t command_total;
    uint16_t sequence;
    uint16_t command;
    float param1;
    float param2;
    float param3;
    float param4;
    int32_t latitude;
    int32_t longitude;
    float altitude;
    uint8_t frame;
};

struct log_MAVLink_Command {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t target_system;
    uint8_t target_component;
    uint8_t source_system;
    uint8_t source_component;
    uint8_t frame;
    uint16_t command;
    float param1;
    float param2;
    float param3;
    float param4;
    int32_t x;
    int32_t y;
    float z;
    uint8_t result;
    bool was_command_long;
};

struct log_PID {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    float   target;
    float   actual;
    float   error;
    float   P;
    float   I;
    float   D;
    float   FF;
    float   Dmod;
    float   slew_rate;
    uint8_t limit;
};

struct log_Mode {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t mode;
    uint8_t mode_num;
    uint8_t mode_reason;
};

/*
  rangefinder - support for 4 sensors
 */
struct log_RFND {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t instance;
    uint16_t dist;
    uint8_t status;
    uint8_t orient;
};

struct log_Arm_Disarm {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t  arm_state;
    uint32_t arm_checks;
    uint8_t forced;
    uint8_t method;
};

// position controller North axis logging
struct log_PSCN {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    float pos_target;
    float pos;
    float vel_desired;
    float vel_target;
    float vel;
    float accel_desired;
    float accel_target;
    float accel;
};

// position controller East axis logging
struct log_PSCE {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    float pos_target;
    float pos;
    float vel_desired;
    float vel_target;
    float vel;
    float accel_desired;
    float accel_target;
    float accel;
};

// position controller Down axis logging
struct log_PSCD {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    float pos_target;
    float pos;
    float vel_desired;
    float vel_target;
    float vel;
    float accel_desired;
    float accel_target;
    float accel;
};

struct log_VER {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t board_type;
    uint16_t board_subtype;
    uint8_t major;
    uint8_t minor;
    uint8_t patch;
    uint8_t fw_type;
    uint32_t git_hash;
    char fw_string[64];
    uint16_t _APJ_BOARD_ID;
};

// @LoggerMessage: MKF0
// @Description: EKF2 beacon sensor diagnostics
struct log_MKF0 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    int16_t gps_hvel[2];
    int16_t gps_vvel;
    int16_t gps_hpos[2];
    int16_t gps_vpos;
    int16_t ev_hvel[2];
    int16_t ev_vvel;
    int16_t ev_hpos[2];
    int16_t ev_vpos;
};

// @LoggerMessage: MKF1
// @Description: EKF2 beacon sensor diagnostics
struct log_MKF1 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    int16_t rng_vpos;
    int16_t baro_vpos;
    int16_t aux_hvel[2];
    int16_t aux_vvel;
    int16_t flow[2];
    int16_t heading;
    int16_t mag_field[3];
};

// @LoggerMessage: MKF2
// @Description: EKF2 beacon sensor diagnostics
struct log_MKF2 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    int16_t drag[2];
    int16_t airspeed;
    int16_t beta;
    int16_t hagl;
    int16_t hagl_rate;
};

// @LoggerMessage: MKF3
// @Description: EKF2 estimator outputs
struct log_MKF3 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    uint64_t control_mode_flags;
    float output_tracking_error[3];
    uint32_t filter_fault_flags;
    float pos_horiz_accuracy;
    float pos_vert_accuracy;
};

// @LoggerMessage: MKF4
// @Description: EKF2 estimator outputs
struct log_MKF4 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    float mag_test_ratio;
    float vel_test_ratio;
    float pos_test_ratio;
    float hgt_test_ratio;
    float tas_test_ratio;
    float hagl_test_ratio;
    float beta_test_ratio;
    float time_slip;
    uint16_t gps_check_fail_flags;
    uint16_t innovation_check_flags;
    uint16_t solution_status_flags;
};

// @LoggerMessage: MKF5
// @Description: EKF2 estimator outputs
struct log_MKF5 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    uint8_t reset_count_vel_ne;
    uint8_t reset_count_vel_d;
    uint8_t reset_count_pos_ne;
    uint8_t reset_count_pod_d;
    uint8_t reset_count_quat;
    uint8_t pre_flt_fail_mag_field_disturbed;
};

struct log_MKF6 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    uint8_t gyro_bias_valid;
    float gyro_bias[3];
    float gyro_bias_variance[3];
};

struct log_MKF7 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    uint8_t accel_bias_valid;
    float accel_bias[3];
    float accel_bias_variance[3];
};

// @LoggerMessage: XKY0,NKY0
// @Description: EKF Yaw Estimator States
// @Field: TimeUS: Time since system startup
// @Field: C: EKF core this data is for
// @Field: YC: GSF yaw estimate (deg)
// @Field: YCS: GSF yaw estimate 1-Sigma uncertainty (deg)
// @Field: Y0: Yaw estimate from individual EKF filter 0 (deg)
// @Field: Y1: Yaw estimate from individual EKF filter 1 (deg)
// @Field: Y2: Yaw estimate from individual EKF filter 2 (deg)
// @Field: Y3: Yaw estimate from individual EKF filter 3 (deg)
// @Field: Y4: Yaw estimate from individual EKF filter 4 (deg)
// @Field: W0: Weighting applied to yaw estimate from individual EKF filter 0
// @Field: W1: Weighting applied to yaw estimate from individual EKF filter 1
// @Field: W2: Weighting applied to yaw estimate from individual EKF filter 2
// @Field: W3: Weighting applied to yaw estimate from individual EKF filter 3
// @Field: W4: Weighting applied to yaw estimate from individual EKF filter 4
struct log_MKF8 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    float yaw_composite;
    float yaw_composite_variance;
    float yaw0;
    float yaw1;
    float yaw2;
    float yaw3;
    float yaw4;
    float wgt0;
    float wgt1;
    float wgt2;
    float wgt3;
    float wgt4;
};

// @LoggerMessage: XKY1,NKY1
// @Description: EKF Yaw Estimator Innovations
// @Field: TimeUS: Time since system startup
// @Field: C: EKF core this data is for
// @Field: IVN0: North velocity innovation from individual EKF filter 0 (m/s)
// @Field: IVN1: North velocity innovation from individual EKF filter 1 (m/s)
// @Field: IVN2: North velocity innovation from individual EKF filter 2 (m/s)
// @Field: IVN3: North velocity innovation from individual EKF filter 3 (m/s)
// @Field: IVN4: North velocity innovation from individual EKF filter 4 (m/s)
// @Field: IVE0: East velocity innovation from individual EKF filter 0 (m/s)
// @Field: IVE1: East velocity innovation from individual EKF filter 1 (m/s)
// @Field: IVE2: East velocity innovation from individual EKF filter 2 (m/s)
// @Field: IVE3: East velocity innovation from individual EKF filter 3 (m/s)
// @Field: IVE4: East velocity innovation from individual EKF filter 4 (m/s)
struct log_MKF9 {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t core;
    float ivn0;
    float ivn1;
    float ivn2;
    float ivn3;
    float ivn4;
    float ive0;
    float ive1;
    float ive2;
    float ive3;
    float ive4;
};

struct log_ARSP {
    APLOG_PACKET_HEADER;
    uint64_t time_us;
    uint8_t instance;
    float   airspeed;
    float   diffpressure;
    int16_t temperature;
    float   rawpressure;
    float   offset;
    uint8_t use;
    uint8_t healthy;
    float   health_prob;
    float   test_ratio;
    uint8_t primary;
};

#pragma pack()
/*----------------------------------variable----------------------------------*/

/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/

/*------------------------------------test------------------------------------*/

#ifdef __cplusplus
}
#endif



